#!/bin/bash -e

set -o pipefail

ROOT=$(realpath $(dirname $0)/..)
MISCDIR=$ROOT/misc
INSTDIR=$ROOT/inst
INSTLOCK=$INSTDIR/startup.lock
LOCALDIR=$ROOT/local
FAUCET_LOG=$INSTDIR/faucet.log
FAUCET_SOCK=faucet_event.sock
export FAUCET_EVENT_SOCK=$INSTDIR/$FAUCET_SOCK
SYSTEM_CONF=system.conf
LOCAL_CONFIG=$LOCALDIR/$SYSTEM_CONF
export DAQ_VERSION=$(git describe --dirty)
TAGGED_VERSION=`cat misc/docker_images.ver`
LSB_RAW=$(lsb_release -a)
export DAQ_LSB_RELEASE=$(echo $LSB_RAW)
export DAQ_SYS_UNAME=$(uname -a)
skip_autostart=
cleanup_file=inst/exrun_cleanup.sh
run_args="$@"

if [ `whoami` != root ]; then
    echo Running as root...
    sudo $0 "$@" && exit 0
    false
fi

if ! git show $TAGGED_VERSION > /dev/null; then
    echo
    echo Tagged version $TAGGED_VERSION not found.
    echo Maybe you need to fetch tags: git fetch --tags
    echo
    false
fi

cd $ROOT
source misc/config_base.sh

while [ -f $INSTLOCK ]; do
    echo Waiting for $INSTLOCK to disappear!
    sleep 10
done

FAUCET=$(realpath $ROOT/faucet)
FORCH=$(realpath $ROOT/forch)
MININET=$(realpath $ROOT/mininet)

if [ ! -d $FAUCET ]; then
    echo Faucet directory $FAUCET not found, try running bin/setup_dev.
    false
fi

if [ ! -d $FORCH ]; then
    echo Forch directory $FORCH not found, try running bin/setup_dev.
    false
fi

(cd $FAUCET; git checkout $(< $ROOT/misc/FAUCET_VERSION)) || \
    echo Could not update faucet, try 'bin/clean_dev && bin/setup_dev' to reset.
(cd $FORCH; git checkout $(< $ROOT/misc/FORCH_VERSION)) || \
    echo Could not update forch, try 'bin/clean_dev && bin/setup_dev' to reset.

echo Release version $DAQ_VERSION

if [ "$1" == "-h" ]; then
    skip_autostart=y
fi

export PYTHONPATH=$FORCH:$FAUCET:$MININET

mkdir -p $INSTDIR
rm -f $INSTDIR/faucet* $cleanup_file

docker ps > /dev/null 2>&1 || service docker start

ovsctl=/usr/share/openvswitch/scripts/ovs-ctl
$ovsctl status || sudo $ovsctl start

function autostart {
    tmp=`mktemp`
    echo DAQ autostart $@
    eval $@ | tee $tmp
    grep -e '^\s*DAQ autoclean\s' $tmp >> $cleanup_file || true
}

function DAQ {
    shift # autoclean
    echo Cleanup $@
    $@ || true
}

if [ -z `which ifconfig` ]; then
    export PATH=/sbin:$PATH
fi

sudo rm -f $cleanup_file
if [ -n "$ext_loip" ]; then
    autostart bin/switch_local
elif [ -n "$ext_ctrl" ]; then
    autostart bin/physical_sec
else
    echo No external switch configured.
fi

# Kill any gateways so that they don't prematurely assign an IP address.
gwids=$(docker ps --format '{{ .Image }} {{ .Names }}' | fgrep daqf/networking | awk '{print $2}') || true
for gwid in $gwids; do
    docker kill $gwid
done

export DAQ_SUPPRESS_PHY_SETUP=y

if [ -z "$skip_autostart" -a -n "$startup_cmds" ]; then
    echo Sourcing $startup_cmds...
    source $startup_cmds
fi

if [ -f .pdbrc ]; then
    echo Found .pdbrc file, using pdb...
    runcmd="python3 -u -m pdb"
elif [ -n "$DAQ_CODECOV" ]; then
    echo Running with codecov analysis...
    runcmd="coverage run --source=daq -a"
else
    runcmd="python3 -u"
fi

if [ -d venv ]; then
    echo Entering virtual python environment...
    source venv/bin/activate
fi

echo Using python3 at `which python3`
echo Executing: $runcmd daq/daq.py $LOCAL_CONFIG $@

export PYTHONDONTWRITEBYTECODE=True
export TERM=dumb

echo Prepending $ROOT/binhack to PATH
export OVSVSCTL_ORIG=`which ovs-vsctl`
export PATH=$ROOT/binhack:$PATH

exit_code=0
$runcmd daq/daq.py $LOCAL_CONFIG $@ || exit_code=$?

if [ -f "$cleanup_file" ]; then
    source $cleanup_file
fi

echo Done with run, exit $exit_code

exit $exit_code
